package com.xyazm.customer.service.impl;

import com.xyazm.common.constants.RedisLockKeyConstants;
import com.xyazm.common.redis.RedisLock;
import com.xyazm.common.utils.ParamCheckUtil;
import com.xyazm.customer.dao.CustomerReceivesAfterSaleInfoDAO;
import com.xyazm.customer.domain.entity.CustomerReceivesAfterSaleInfoDO;
import com.xyazm.customer.domain.param.CustomerAuditAfterSaleParam;
import com.xyazm.customer.domain.param.ReceiveAfterSaleAuditParam;
import com.xyazm.customer.exception.CustomerBizException;
import com.xyazm.customer.exception.CustomerErrorCodeEnum;
import com.xyazm.customer.mapstruct.CustomerApiMapstruct;
import com.xyazm.customer.remote.OrderAfterSaleRemote;
import com.xyazm.customer.service.ICustomerService;
import com.xyazm.order.api.IOrderAfterSaleApi;
import com.xyazm.order.domain.param.ReceiveCustomerAfterSaleParam;
import com.xyazm.order.domain.param.ReceiveCustomerAuditResultParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author xuyou
 * @date 2022年07月20日 8:30
 */
@Slf4j
@Service
public class CustomerServiceImpl implements ICustomerService {

    @DubboReference(version = "1.0.0")
    private IOrderAfterSaleApi orderAfterSaleApi;
    @Autowired
    private RedisLock redisLock;
    @Autowired
    private CustomerReceivesAfterSaleInfoDAO customerReceivesAfterSaleInfoDAO;
    @Autowired
    private OrderAfterSaleRemote orderAfterSaleRemote;



    @Override
    public void receiveAfterSaleAudit(ReceiveAfterSaleAuditParam param) {
        log.info("客服接收审核售后申请,param:{}",param);
        // 参数校验
        checkReceiveAfterSaleAuditParam(param);
        // 获取分布式锁
        String afterSaleId = param.getAfterSaleId();
        String key = RedisLockKeyConstants.REFUND_KEY + afterSaleId;
        boolean lock = redisLock.tryLock(key);
        if (!lock) {
            throw new CustomerBizException(CustomerErrorCodeEnum.PROCESS_RECEIVE_AFTER_SALE_REPEAT);
        }
        try {
            ReceiveCustomerAfterSaleParam receiveCustomerAuditResultParam =
                    CustomerApiMapstruct.INSTANCE.convertReceiveCustomerAfterSaleParam(param);
            // 获取售后支付单id
            Long afterSaleRefundId = orderAfterSaleRemote.customerFindAfterSaleRefundInfo(receiveCustomerAuditResultParam);
            // 保存售后申请数据
            CustomerReceivesAfterSaleInfoDO customerReceivesAfterSaleInfoDO =
                    CustomerApiMapstruct.INSTANCE.convertCustomerReceivesAfterSaleInfo(param);
            customerReceivesAfterSaleInfoDO.setAfterSaleRefundId(afterSaleRefundId);
            customerReceivesAfterSaleInfoDAO.save(customerReceivesAfterSaleInfoDO);
            log.info("客服保存售后申请信息成功,afterSaleId:{}", customerReceivesAfterSaleInfoDO.getAfterSaleId());
        } catch (Exception e) {
            log.error("receiveAfterSaleAudit error",e);
            throw new CustomerBizException(CustomerErrorCodeEnum.SAVE_AFTER_SALE_INFO_FAILED);
        } finally {
            //  放锁
            redisLock.unlock(key);
        }
    }


    @Override
    public void customerAuditAfterSale(CustomerAuditAfterSaleParam param) {
        String orderId = param.getOrderId();
        //  分布式锁
        String key = RedisLockKeyConstants.REFUND_KEY + orderId;
        boolean lock = redisLock.tryLock(key);
        if (!lock) {
            throw new CustomerBizException(CustomerErrorCodeEnum.CUSTOMER_AUDIT_CANNOT_REPEAT);
        }
        try {
            ReceiveCustomerAuditResultParam receiveCustomerAuditResultParam =
                    CustomerApiMapstruct.INSTANCE.convertReceiveCustomerAuditResultParam(param);
            orderAfterSaleRemote.receiveCustomerAuditResult(receiveCustomerAuditResultParam);
        } finally {
            redisLock.unlock(key);
        }
    }


    /**
     * 校验客服接收审核售后申请入参
     * @author xuyou
     * 2022/7/27 0027 22:22
     * @param param
    */
    private void checkReceiveAfterSaleAuditParam(ReceiveAfterSaleAuditParam param) {
        ParamCheckUtil.checkStringNonEmpty(param.getUserId(), CustomerErrorCodeEnum.USER_ID_IS_NULL);
        ParamCheckUtil.checkStringNonEmpty(param.getOrderId(), CustomerErrorCodeEnum.ORDER_ID_IS_NULL);
        ParamCheckUtil.checkStringNonEmpty(param.getAfterSaleId(), CustomerErrorCodeEnum.AFTER_SALE_ID_IS_NULL);
        ParamCheckUtil.checkObjectNonNull(param.getAfterSaleRefundId(), CustomerErrorCodeEnum.AFTER_SALE_REFUND_ID_IS_NULL);
        ParamCheckUtil.checkObjectNonNull(param.getAfterSaleType(), CustomerErrorCodeEnum.AFTER_SALE_TYPE_IS_NULL);
        ParamCheckUtil.checkObjectNonNull(param.getReturnGoodAmount(), CustomerErrorCodeEnum.RETURN_GOOD_AMOUNT_IS_NULL);
        ParamCheckUtil.checkObjectNonNull(param.getApplyRefundAmount(), CustomerErrorCodeEnum.APPLY_REFUND_AMOUNT_IS_NULL);
    }
}
